#include "stdafx.h"
#include "gamecreator.h"
#include "admindbmanager.h"
#include "random.h"

GameCreator::GameCreator( int topicCategory, int topicCount, const QVector<int> & values )
:   m_topicCategory( topicCategory ),
    m_topicCount( topicCount ),
    m_values( values )
{
}

GameCreator::~GameCreator()
{
}

bool GameCreator::createGame()
{
    QVector<qint64> topicIdVector;
    if (! TopicDbManager::readTopicsIdVector( m_topicCategory, m_values.count(), topicIdVector ))
        return false;

    if (topicIdVector.count() < m_topicCount)
    {
        errorBox( QObject::tr( "Not enough topic with this properties." ) );
        return false;
    }

    topicIdVector = randomTopicIdVector( topicIdVector );
    return createGameTopicVector( topicIdVector );
}

QVector<qint64> GameCreator::randomTopicIdVector( QVector<qint64> & topicIdVector ) const
{
    QVector<qint64> idVector;
    while (idVector.count() < m_topicCount)
    {
        int index = Random::random().random( 0, topicIdVector.count() - 1 );
        idVector.push_back( topicIdVector.at( index ) );
        topicIdVector.remove( index );
    }

    return idVector;
}

bool GameCreator::createGameTopicVector( const QVector<qint64> & topicIdVector )
{
    QVector<qint64>::const_iterator it;
    FOREACH (it, topicIdVector)
    {
        Topic topic;
        QVector<Question> questionVector;
        if (! TopicDbManager::selectTopicDetailsFromDb( * it, topic ))
            return false;

        questionVector = selectQuestionVectorFollowingValues( topic.questionVector );
        topic.questionVector = questionVector;

        m_topicVector.push_back( topic );
    }

    return true;
}

QVector<Question> GameCreator::selectQuestionVectorFollowingValues( const QVector<Question> & questionVector ) const
{
    QVector<Question> q;
    QMap<qint64, int> questionValueMap;
    QVector<Question>::const_iterator it;
    FOREACH (it, questionVector)
        questionValueMap.insert( it->id, it->value );

    QVector<int>::const_iterator iter;
    FOREACH (iter, m_values)
    {
        while (1)
        {
            qint64 questionId;
            int value = Random::random().questionValue( * iter );
            if (findValueInMap( questionValueMap, value, questionId ))
            {
                FOREACH (it, questionVector)
                {
                    if (it->id == questionId)
                    {
                        q.push_back( * it );
                        questionValueMap.erase( questionValueMap.find( questionId ) );
                        goto endWhile;
                    }
                }
            }
        }

        endWhile:;
    }

    return q;
}

bool GameCreator::findValueInMap( const QMap<qint64, int> & questionValueMap, int value, qint64 & questionId ) const
{
    QVector<qint64> questionIds;
    QMap<qint64, int>::const_iterator it;
    FOREACH (it, questionValueMap)
    {
        if (it.value() == value)
        {
            questionIds.push_back( it.key() );
        }
    }

    if (questionIds.isEmpty())
        return false;

    int index = Random::random().random( 0, questionIds.count() - 1 );
    questionId = questionIds.at( index );
    return true;
}

const QVector<Topic> & GameCreator::topicVector()
{
    return m_topicVector;
}
